Add expensive parser functions {{REVISION*:}}
authorumherirrender <umherirrender_de.wp@web.de>
Tue, 29 Oct 2013 21:02:59 +0000 (22:02 +0100)
committerumherirrender <umherirrender_de.wp@web.de>
Tue, 29 Oct 2013 21:02:59 +0000 (22:02 +0100)
The magic words REVISIONID, REVISIONUSER and REVISIONTIMESTAMP (with
friends) now exists as parser function to fetch revision information
from another page specified as param to the parser function.

Invalid title or non-existing title will return an empty string.
Requesting revision deleted information will always return an empty
string, because this is for public audience and goes into the parser
cache.

The parser function will register a template link to get updated with
refresh jobs on edit of the remote page. This is the same way, than
the parser function pagesize is working.

When the given param is equal to the current title of the parser, the
parser function will yield the previous versions on preview and on
substitution, that includes empty strings when used on page creation,
but using the values from the current version for page view, including
viewing old revisions.

Bug: 6092
Change-Id: Ib15a4e54c65192ec3caef71fd5dcb93fb6fc444e

RELEASE-NOTES-1.23
includes/parser/CoreParserFunctions.php
includes/parser/Parser.php

index 6c78253..711b8a9 100644 (file)
@@ -18,6 +18,8 @@ production.
   This capability can be enabled by setting $wgResourceLoaderStorageEnabled to
   true. This feature is currently considered experimental and should only be
   enabled with care.
+* (bug 6092) Add expensive parser functions {{REVISIONID:}}, {{REVISIONUSER:}}
+  and {{REVISIONTIMESTAMP:}} (with friends).
 
 === Bug fixes in 1.23 ===
 * (bug 41759) The "updated since last visit" markers (on history pages, recent
index 4b6eeca..44c7458 100644 (file)
@@ -100,6 +100,15 @@ class CoreParserFunctions {
                $parser->setFunctionHook( 'subjectpagenamee', array( __CLASS__, 'subjectpagenamee' ), SFH_NO_HASH );
                $parser->setFunctionHook( 'tag',              array( __CLASS__, 'tagObj'           ), SFH_OBJECT_ARGS );
                $parser->setFunctionHook( 'formatdate',       array( __CLASS__, 'formatDate'       ) );
+               $parser->setFunctionHook( 'pageid',           array( __CLASS__, 'pageid'           ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisionid',       array( __CLASS__, 'revisionid'       ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisionday',      array( __CLASS__, 'revisionday'      ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisionday2',     array( __CLASS__, 'revisionday2'     ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisionmonth',    array( __CLASS__, 'revisionmonth'    ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisionmonth1',   array( __CLASS__, 'revisionmonth1'   ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisionyear',     array( __CLASS__, 'revisionyear'     ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisiontimestamp', array( __CLASS__, 'revisiontimestamp' ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'revisionuser',     array( __CLASS__, 'revisionuser'     ), SFH_NO_HASH );
 
                if ( $wgAllowDisplayTitle ) {
                        $parser->setFunctionHook( 'displaytitle', array( __CLASS__, 'displaytitle' ), SFH_NO_HASH );
@@ -707,29 +716,15 @@ class CoreParserFunctions {
         * @return string
         */
        static function pagesize( $parser, $page = '', $raw = null ) {
-               static $cache = array();
                $title = Title::newFromText( $page );
 
                if ( !is_object( $title ) ) {
-                       $cache[$page] = 0;
                        return self::formatRaw( 0, $raw );
                }
 
-               # Normalize name for cache
-               $page = $title->getPrefixedText();
-
-               $length = 0;
-               if ( isset( $cache[$page] ) ) {
-                       $length = $cache[$page];
-               } elseif ( $parser->incrementExpensiveFunctionCount() ) {
-                       $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
-                       $pageID = $rev ? $rev->getPage() : 0;
-                       $revID = $rev ? $rev->getId() : 0;
-                       $length = $cache[$page] = $rev ? $rev->getSize() : 0;
-
-                       // Register dependency in templatelinks
-                       $parser->mOutput->addTemplate( $title, $pageID, $revID );
-               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $title );
+               $length = $rev ? $rev->getSize() : 0;
                return self::formatRaw( $length, $raw );
        }
 
@@ -949,4 +944,204 @@ class CoreParserFunctions {
                );
                return $parser->extensionSubstitution( $params, $frame );
        }
+
+       /**
+        * Fetched the current revision of the given title and return this.
+        * Will increment the expensive function count and
+        * add a template link to get the value refreshed on changes.
+        * For a given title, which is equal to the current parser title,
+        * the revision object from the parser is used, when that is the current one
+        *
+        * @param $parser Parser
+        * @param $title Title
+        * @return Revision
+        * @since 1.23
+        */
+       private static function getCachedRevisionObject( $parser, $title = null ) {
+               static $cache = array();
+
+               if ( is_null( $title ) ) {
+                       return null;
+               }
+
+               // Use the revision from the parser itself, when param is the current page
+               // and the revision is the current one
+               if ( $title->equals( $parser->getTitle() ) ) {
+                       $parserRev = $parser->getRevisionObject();
+                       if ( $parserRev && $parserRev->isCurrent() ) {
+                               // force reparse after edit with vary-revision flag
+                               $parser->getOutput()->setFlag( 'vary-revision' );
+                               wfDebug( __METHOD__ . ": use current revision from parser, setting vary-revision...\n" );
+                               return $parserRev;
+                       }
+               }
+
+               // Normalize name for cache
+               $page = $title->getPrefixedDBkey();
+
+               if ( array_key_exists( $page, $cache ) ) { // cache contains null values
+                       return $cache[$page];
+               }
+               if ( $parser->incrementExpensiveFunctionCount() ) {
+                       $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
+                       $pageID = $rev ? $rev->getPage() : 0;
+                       $revID = $rev ? $rev->getId() : 0;
+                       $cache[$page] = $rev; // maybe null
+
+                       // Register dependency in templatelinks
+                       $parser->getOutput()->addTemplate( $title, $pageID, $revID );
+
+                       return $rev;
+               }
+               $cache[$page] = null;
+               return null;
+       }
+
+       /**
+        * Get the pageid of a specified page
+        * @param $parser Parser
+        * @param $title string Title to get the pageid from
+        * @since 1.23
+        */
+       public static function pageid( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // Use title from parser to have correct pageid after edit
+               if ( $t->equals( $parser->getTitle() ) ) {
+                       $t = $parser->getTitle();
+               }
+               // fetch pageid from cache/database and return the value
+               $pageid = $t->getArticleID();
+               return $pageid ? $pageid : '';
+       }
+
+       /**
+        * Get the id from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the id from
+        * @since 1.23
+        */
+       public static function revisionid( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? $rev->getId() : '';
+       }
+
+       /**
+        * Get the day from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the day from
+        * @since 1.23
+        */
+       public static function revisionday( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'j' ) : '';
+       }
+
+       /**
+        * Get the day with leading zeros from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the day from
+        * @since 1.23
+        */
+       public static function revisionday2( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'd' ) : '';
+       }
+
+       /**
+        * Get the month with leading zeros from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the month from
+        * @since 1.23
+        */
+       public static function revisionmonth( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'm' ) : '';
+       }
+
+       /**
+        * Get the month from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the month from
+        * @since 1.23
+        */
+       public static function revisionmonth1( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'n' ) : '';
+       }
+
+       /**
+        * Get the year from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the year from
+        * @since 1.23
+        */
+       public static function revisionyear( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'Y' ) : '';
+       }
+
+       /**
+        * Get the timestamp from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the timestamp from
+        * @since 1.23
+        */
+       public static function revisiontimestamp( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'YmdHis' ) : '';
+       }
+
+       /**
+        * Get the user from the last revision of a specified page.
+        * @param $parser Parser
+        * @param $title string Title to get the user from
+        * @since 1.23
+        */
+       public static function revisionuser( $parser, $title = null ) {
+               $t = Title::newFromText( $title );
+               if ( is_null( $t ) ) {
+                       return '';
+               }
+               // fetch revision from cache/database and return the value
+               $rev = self::getCachedRevisionObject( $parser, $t );
+               return $rev ? $rev->getUserText() : '';
+       }
 }
index 1f14223..be7fc03 100644 (file)
@@ -5760,8 +5760,9 @@ class Parser {
         * Get the revision object for $this->mRevisionId
         *
         * @return Revision|null either a Revision object or null
+        * @since 1.23 (public since 1.23)
         */
-       protected function getRevisionObject() {
+       public function getRevisionObject() {
                if ( !is_null( $this->mRevisionObject ) ) {
                        return $this->mRevisionObject;
                }